#include "settings.h"

SVar::SVar() {
	VarType=NULL_TYPE;
	return;
}

CSettings::CSettings(std::string Filename){
	GetSettings(Filename);
}

bool CSettings::GetSettings(std::string Filename) {
	// Read the ini file.
	std::ifstream File;
	File.open (Filename.c_str(), std::ios::in);
	if (File.is_open()) {
		while (! File.eof() ) {
			std::string Line;
			std::getline(File,Line);
			LineVector.push_back(Line);
		}
	File.close();
	} else {
		fprintf(stderr, "Error: Cannot open file \"%s\" for parsing.\n",
				const_cast<char *>(Filename.c_str()));
		return false;
	}
	// Temp placeholder for the Type string. Note that all Names that
	// did not have a previous Type declared before them, will
	// automatically have their Type as an empty string, or "".
	std::string TypeName="";
	// For every line in the string vector...
	for (std::vector<std::string>::iterator itr=LineVector.begin();LineVector.end() != itr; ++itr) {
		// Start to parse:
		// Skip empty or comment lines.
		if ('#'==(*itr)[0] || 0==itr->length())
			continue;
		// Extract the type part of the following settings names, of
		// the syntax [type].
		if ('['==(*itr)[0]) {
			std::string::size_type Start = itr->find("[", 0);
			std::string::size_type End = itr->find("]", 0);
			TypeName = itr->substr(Start+1, End-1);
			// Convert to lower case.
			for (unsigned int i=0; i<TypeName.length(); ++i)
				TypeName[i]=tolower(TypeName[i]);
//			fprintf(stderr, "\"%s\"!\n",TypeName.c_str());
		}

		// Extract the float value from the string, and the Name from
		// the Name=value syntax lines.
		std::string::size_type Loc = itr->find("=", 0);
		if(Loc != std::string::npos) {
			// Make sure the Value does not contain two quotation marks
			// (") inside it, in which case it means the Value is of
			// numerical type, and not string.
			std::string::size_type Loc2 = itr->find("\"", 0);
			Loc2 = itr->find("\"", Loc2+1);
			if (Loc2 == std::string::npos) {
				float TempValue=0;
				std::string TempString;
				TempString = itr->substr(Loc+1);
				// Casting string to float.
				TempValue=atof(TempString.c_str());
				std::string TempName = itr->substr(0,Loc);
				// Convert to lower case.
				for (unsigned int i=0; i<TempName.length(); ++i)
					TempName[i]=tolower(TempName[i]);
				//fprintf(stderr, "\"%s\" is actually: %f!\n",TempName.c_str(), TempValue);
				// And eventually, store all the data in the list.
				AddNumVar(TypeName, TempName, TempValue);
			// Or else, if it is the quotation mark, it is a string.
			} else {
				std::string TempValue;
				std::string TempString;
				TempString = itr->substr(Loc+2);
				// Casting string to float.
				TempValue=TempString.substr(0, TempString.length()-1);
				std::string TempName = itr->substr(0,Loc);
				// Validate the Value string, make sure its not empty.
				if ("\"\""==itr->substr(Loc+1,2))
					TempValue="";
				// Convert to lower case.
				for (unsigned int i=0; i<TempName.length(); ++i)
					TempName[i]=tolower(TempName[i]);
//				for (unsigned int i=0; i<TempValue.length(); ++i)
//					TempValue[i]=tolower(TempValue[i]);
				//std::cerr << TempString << "\n Length:"  << TempString.length() << std::endl;
				//std::cerr << TempName << " is actually: \"" << TempValue << "\"" << std::endl;
				// And eventually, store all the data in the list.
				AddStrVar(TypeName, TempName, TempValue);
				//fprintf(stderr, "%s|%s\n",TempName.c_str(),TempValue.c_str());
			}
		}

	}
	return true;
}

// Add a variable to the settings list.
int CSettings::AddNumVar(std::string Type, std::string Name, float Value){
	SVar TempVar;
	TempVar.VarType=NUMBER_TYPE;
	TempVar.NValue=Value, TempVar.Name=Name, TempVar.Type=Type;
	SettingList.push_back(TempVar);
	return 0;
}

// Add a variable to the settings list.
int CSettings::AddStrVar(std::string Type, std::string Name, std::string Value){
	SVar TempVar;
	TempVar.VarType=STRING_TYPE;
	TempVar.SValue=Value, TempVar.Name=Name, TempVar.Type=Type;
	SettingList.push_back(TempVar);
	return 0;
}

float CSettings::GetNValue(std::string Type, std::string Name, float Default) {
	// Convert to lower case both strings.
	for (unsigned int i=0; i<Type.length(); ++i)
		Type[i]=tolower(Type[i]);
	for (unsigned int i=0; i<Name.length(); ++i)
		Name[i]=tolower(Name[i]);
	std::vector<SVar>::iterator itr;
	for (itr=SettingList.begin(); itr!=SettingList.end();++itr)
		if (Type==itr->Type)
			if (Name==itr->Name)
				if (NUMBER_TYPE==itr->VarType)
					return itr->NValue;
	// Return the default value if did not find the requested Type//Name in
	// the list.
	return Default;
}

std::string CSettings::GetSValue(std::string Type, std::string Name, std::string Default) {
	// Convert to lower case both strings.
	for (unsigned int i=0; i<Type.length(); ++i)
		Type[i]=tolower(Type[i]);
	for (unsigned int i=0; i<Name.length(); ++i)
		Name[i]=tolower(Name[i]);
	std::vector<SVar>::iterator itr;
	for (itr=SettingList.begin(); itr!=SettingList.end();++itr)
		if (Type==itr->Type)
			if (Name==itr->Name)
				if (STRING_TYPE==itr->VarType)
					return itr->SValue;
	// Return the default value if did not find the requested Type//Name in
	// the list.
	return Default;
}

